<?php
/**
 * Helper général des fichiers custom 
 *
 */
    defined('_JEXEC') or die('Acces interdit');
    
    
    class AmapHelper {
        
        /* Retourne les codes des Familles de produit avec leurs 
			- ID 
			- Code
			- Libellé
         */
        public static function getProductsFamilies() { 
		
            //Recherche la catégorie de tête des produits (roleObjet = 'Produits')			
            $idProduits = self::getAmapObjectId(ERoleObjet::ERoleObjetProduits);	

            //Query definition
            $db = JFactory::getDBO();			
            $query = $db->getQuery(true);
            $query->select($db->quoteName(array('#__categories.id', '#__categories.title', '#__categories.metakey'), array('id','libelle','code')));			
            $query->from($db->quoteName('#__categories'));           
            $query->where($db->quoteName('#__categories.parent_id') . ' = '. $db->quote((int) $idProduits));
            $query->where($db->quoteName('#__categories.metakey') . " LIKE '%".ECaracObjet::ECaracObjetRole."=".ERoleObjet::ERoleObjetFamilleProduits."%'");
            $query->order($db->quoteName('#__categories.title') . ' ASC');

            // Reset the query using our newly populated query object.
            $db->setQuery($query);

            // Load the results as an associative array
            $resultatsBruts = $db->loadAssocList();
            
            //extrait un paramètre du champ custom et l'ajoute au tableau à la place du champ custom
            $resultats = self::getCustomParameters($resultatsBruts, 'code', ECaracObjet::ECaracObjetCodeFamilleProduit);

            return $resultats;
        }
	    
        
        /**
         * renvoie la liste des distributions d'une opération donnée. Renvoie un tableau associatif 
         * conteant la liste des distributions, avec pour chacune un triplet 'id, libelle, date'
         * 
         * @param type $codeOperation  = code de l'opération
         */
        public static function getDistributions($codeOperation) { 
            
             //Query definition
            $db = JFactory::getDBO();			
            $query = $db->getQuery(true);
            $query->select($db->quoteName(array('#__eb_events.id', '#__eb_events.title', '#__eb_events.event_date'), array('id','libelle','date')));			
            $query->from($db->quoteName("#__eb_events"));
            $query->join('INNER', $db->quoteName('#__eb_event_categories') . ' ON (' . $db->quoteName('#__eb_events.id') . ' = ' . $db->quoteName('#__eb_event_categories.event_id') . ')');
            $query->join('INNER', $db->quoteName('#__eb_categories') . ' ON (' . $db->quoteName('#__eb_event_categories.category_id') . ' = ' . $db->quoteName('#__eb_categories.id') . ')');
            $query->where($db->quoteName("#__eb_categories.meta_keywords")." LIKE '%".ECaracObjet::ECaracObjetCodeOperation."=".$codeOperation."%'");
            $query->where($db->quoteName("#__eb_events.meta_keywords")." LIKE '%".ECaracObjet::ECaracObjetRole."=".ERoleObjet::ERoleObjetDistribution."%'");
            $query->order($db->quoteName('#__eb_events.event_date') . ' ASC');
            
            // Load the results as an associative array
            $db->setQuery($query);            
            $resultats = $db->loadAssocList();
            
            return $resultats;
            
        }                
        
        /**
         * Cherche l'id de l'event qui correspond à une opération donnée
         * 
         * @param type $codeOperation
         */
        function getOperationId($codeOperation){
            
            //Query definition
            $db = JFactory::getDBO();			
            $query = $db->getQuery(true);
            $query->select($db->quoteName(array('#__eb_events.id'), array('id')));			
            $query->from($db->quoteName("#__eb_events"));
            $query->join('INNER', $db->quoteName('#__eb_event_categories') . ' ON (' . $db->quoteName('#__eb_events.id') . ' = ' . $db->quoteName('#__eb_event_categories.event_id') . ')');
            $query->join('INNER', $db->quoteName('#__eb_categories') . ' ON (' . $db->quoteName('#__eb_event_categories.category_id') . ' = ' . $db->quoteName('#__eb_categories.id') . ')');
            $query->where($db->quoteName("#__eb_categories.meta_keywords")." LIKE '%".ECaracObjet::ECaracObjetCodeOperation."=".$codeOperation."%'");
            $query->where($db->quoteName("#__eb_events.meta_keywords")." LIKE '%".ECaracObjet::ECaracObjetRole."=".ERoleObjet::ERoleObjetSuiviOperation."%'");
            $query->order($db->quoteName('#__eb_events.event_date') . ' ASC');
            
            $db->setQuery($query);            
            $resultats = $db->loadAssocList();
            $idLu = 0;
            if (count($resultats) == 1) {
                $idLu = $resultats[0]['id'];
            };
            return (int) $idLu;
            
        }
        
        /**
         * REnvoie les souscripteurs d'une opération, ainsi que le montannt total de la souscription
         * @param type $codeOperation
         * @return type
         */
        function getOperationSubscriptions($codeOperation){
            
            //Query definition
            $db = JFactory::getDBO();			
            $query = $db->getQuery(true);
            $query->select($db->quoteName(array('#__invoices_contacts.name', '#__invoices_invoices.computed_total'), array('nom','montanttotal')));			
            $query->from($db->quoteName("#__invoices_invoices"));
            $query->join('INNER', $db->quoteName('#__invoices_contacts') . ' ON (' . $db->quoteName('#__invoices_contacts.id') . ' = ' . $db->quoteName('#__invoices_invoices.user_id') . ')');       
            $query->where($db->quoteName("#__invoices_invoices.external_type")." LIKE '%".ECaracObjet::ECaracObjetCodeOperation."=".$codeOperation."%'");
            $query->order($db->quoteName('#__invoices_contacts.name') . ' ASC');
            
            $db->setQuery($query);            
            $resultats = $db->loadAssocList();           
            return $resultats;
            
        }
            
 
            
        /**
         * Renvoie la liste des opérations, en fonction des paramètres passés. Renvoie un tableau associatif 
         * conteant la liste des opérations, avec pour chacune un quadruplet 'id, libelle, datefinsouscrption, code, codeparent'
         * (si $codeFamilleProduits est précisé, codeparent = $codeFamilleProduits)
         * 
         * @param type $codeFamilleProduits : Si pas de code famille, cherche dans toutes les familles
         * @param type $uniquementPubliee  : Si égal à true, ne recherche que dans les categories publiées sinon toutes
         * @param type $estEnCours  : Si égal à true, prend uniquement celles dont l'évenement de suivi a une date limite d'inscription non passée, sinon toutes
         */
        public static function getOperations($codeFamilleProduits = '', $uniquementPubliee = true, $etatSouscription = 'encours') { 
                      
            //Query definition
            $db = JFactory::getDBO();			
            $query = $db->getQuery(true);
            $query->select($db->quoteName(array('#__eb_events.id', '#__eb_categories.name', '#__eb_events.cut_off_date', '#__eb_events.event_date', '#__eb_categories.meta_keywords', 'parent_categories.meta_keywords'), array('id','libelle','datefinsouscription', 'datedebutoperation','code', 'codeparent')));			
            $query->from($db->quoteName("#__eb_events"));
            $query->join('INNER', $db->quoteName('#__eb_event_categories') . ' ON (' . $db->quoteName('#__eb_events.id') . ' = ' . $db->quoteName('#__eb_event_categories.event_id') . ')');
            $query->join('INNER', $db->quoteName('#__eb_categories') . ' ON (' . $db->quoteName('#__eb_event_categories.category_id') . ' = ' . $db->quoteName('#__eb_categories.id') . ')');
            $query->join('INNER', $db->quoteName('#__eb_categories','parent_categories') . ' ON (' . $db->quoteName('#__eb_categories.parent') . ' = ' . $db->quoteName('parent_categories.id') . ')');            
            $query->where($db->quoteName("#__eb_events.meta_keywords")." LIKE '%".ECaracObjet::ECaracObjetRole."=".ERoleObjet::ERoleObjetSuiviOperation."%'");
            
            //clauses optionelles
            if ($codeFamilleProduits !== '') {
                $query->where($db->quoteName("parent_categories.meta_keywords")." LIKE '%".ECaracObjet::ECaracObjetCodeFamilleProduit."=".$codeFamilleProduits."%'");
            }
 
            if ($uniquementPubliee === true) {
                $query->where($db->quoteName("#__eb_events.published")." = true ");
                $query->where($db->quoteName("#__eb_categories.published")." = true ");
                $query->where($db->quoteName("parent_categories.published")." = true ");
            }
            
            switch ($etatSouscription) {
                case 'encours':
                    $query->where($db->quoteName("#__eb_events.cut_off_date")." >= '".self::convertDateToMySQL()."'");
                    break;

                case 'afinaliser':
                    $query->where($db->quoteName("#__eb_events.cut_off_date")." < '".self::convertDateToMySQL()."'");
                    $query->where($db->quoteName("#__eb_events.event_date")." >= '".self::convertDateToMySQL()."'");
                    $query->where($db->quoteName("#__eb_events.custom_fields")." NOT LIKE '%operationfinalisee=\"1\"%'");
                    break;
            } 

            // Load the results as an associative array
            $db->setQuery($query);            
            $resultatsBruts = $db->loadAssocList();
            
            //remplace les champs "metakey" par la valeur voulue (code et codeparent)
            $resultats = self::getCustomParameters($resultatsBruts, 'codeparent', ECaracObjet::ECaracObjetCodeFamilleProduit);
            $resultats = self::getCustomParameters($resultatsBruts, 'code', ECaracObjet::ECaracObjetCodeOperation);
            
            return $resultats;
            
        }
        
        /**
         * extrait un paramètre du champ custom du tableau et l'ajoute au tableau à la place du champ custom
         * 
         */
         public static function getCustomParameters($results, $customField, $parameterName) {
             
             for ($i=0;$i<count($results);$i++) {
                 $assignations = explode(";", $results[$i][$customField]);
                 $parameterValue = '';
                 for ($j=0;$j<count($assignations);$j++) {
                     $parameters = explode("=", $assignations[$j]);
                     if ($parameters[0] == $parameterName) {
                         $parameterValue = $parameters[1];
                     }
                 }
                 //remplace la valeur du champ 'custom' par la valeur trouvée
                 $results[$i][$customField] = $parameterValue;                 
             }
             
             return $results;
         }
		
        //retourne l'id d'un objet Amap en fonction de son rôle et de son type
        /**
         * un objet Amap est un objet utilisé par l'un des composants (evenement, catégorie d'evenement,
         * article utilisé comme produit, ...)
         * 
         * @param type $objectRole
         * @param type $objectType
         * @return int id 
         */        
        public static function getAmapObjectId($objectRole, $codeFamille = '') {

            $fieldTable = '';
            $clause1 = '';
            $clause2 = '';
            switch ($objectRole) {
                    case ERoleObjet::ERoleObjetProduits :
                            $fieldTable = "#__categories";
                            $fieldName = "metakey";
                            $clause1 = " LIKE '%".ECaracObjet::ECaracObjetRole."=".ERoleObjet::ERoleObjetProduits."%'";
                            break;

                    case ERoleObjet::ERoleObjetFamilleProduits :
                            $fieldTable = '#__categories';
                            $fieldName = "metakey";
                            $clause1 = " LIKE '%".ECaracObjet::ECaracObjetRole."=".ERoleObjet::ERoleObjetFamilleProduits."%'";
                            $clause2 = " LIKE '%".ECaracObjet::ECaracObjetCodeFamilleProduit."=".$codeFamille."%'";
                            break;
                        
                    case ERoleObjet::ERoleObjetOperations :
                            $fieldTable = '#__eb_categories';    
                            $fieldName = "meta_keywords";
                            $clause1 = " LIKE '%".ECaracObjet::ECaracObjetRole."=".ERoleObjet::ERoleObjetOperations."%'";
                            break;
                        
                    case ERoleObjet::ERoleObjetFamilleOperations :
                            $fieldTable = '#__eb_categories';
                            $fieldName = "meta_keywords";
                            $clause1 = " LIKE '%".ECaracObjet::ECaracObjetRole."=".ERoleObjet::ERoleObjetFamilleOperations."%'";
                            $clause2 = " LIKE '%".ECaracObjet::ECaracObjetCodeFamilleProduit."=".$codeFamille."%'";
                            break;

                    case ERoleObjet::ERoleObjetOperationsCourantes :
                            $fieldTable = '#__eb_categories';
                            $fieldName = "meta_keywords";
                            $clause1 = " LIKE '%".ECaracObjet::ECaracObjetRole."=".ERoleObjet::ERoleObjetOperationsCourantes."%'";
                            break;
                        
                    default:
                            return 0;
            }

            //Query definition
            $db = JFactory::getDBO();			
            $query = $db->getQuery(true);
            $query->select($db->quoteName('id'));			
            $query->from($db->quoteName($fieldTable));
            if ($clause1 !== '') $query->where($db->quoteName($fieldName).$clause1);
            if ($clause2 !== '') $query->where($db->quoteName($fieldName).$clause2);
           
            //Execute query
            $db->setQuery($query);
            $results = $db->loadAssocList();
            $return = 0;

            //ne peut retourner qu'une seule valeur
            if (count($results) !== 1) {
                    return 0;			
            } else {
                if (is_numeric($results[0]['id'])) {
                    $return = intval($results[0]['id']);
                }
                return $return;
            }		

         }         
         
        /* Créée une categorie d'evenement directement en base de données
         * renvoie l'ID de la catégorie créée
         */
        public static function createEventCategory($parent, $name, $description, $ordering, $published, $access, $colorCode, $metakey) {
        
            // Crée un objet contenant les paramètres de la catégorie
            $newCategory = new stdClass();
            $newCategory->parent = $parent;
            $newCategory->name = $name;
            $newCategory->description = $description;
            $newCategory->ordering = $ordering;
            $newCategory->published = $published;
            $newCategory->access = $access;
            $newCategory->color_code = $colorCode;
            $newCategory->meta_keywords = $metakey;

            // Insert the object into the event category table
            $db = JFactory::getDbo();
            $result = $db->insertObject('#__eb_categories', $newCategory, 'id');            
            if (!$result) {
                return 0;
            } else {
                return (int)$db->insertid();
            }          
            
        }
         
            
        /* Créée un evenement directement en base de données
        * renvoie l'ID de l'évenement créé
        */
        public static function createEvent ($title, $parentCategories, $eventDate, $eventEndDate, $createdBy, $registrationType, $cutOffDate, $enableCancelRegistration, $cancelBeforeDate, $published, $metakey = '', $customFields = '') {

            $newEvent = new stdClass();
            $newEvent->title = $title;
            $newEvent->registration_type = $registrationType;
            $newEvent->created_by =$createdBy;
            $newEvent->event_end_date = self::convertDateToMySQL($eventEndDate);
            $newEvent->event_date = self::convertDateToMySQL($eventDate);
            $newEvent->cut_off_date = self::convertDateToMySQL($cutOffDate);
            $newEvent->enable_cancel_registration = $enableCancelRegistration;
            $newEvent->cancel_before_date = self::convertDateToMySQL($cancelBeforeDate);
            $newEvent->published = $published;
            $newEvent->meta_keywords = $metakey;
            $newEvent->custom_fields = $customFields;

            // Insert the object into the event table
            $db = JFactory::getDbo();
            $result = $db->insertObject('#__eb_events', $newEvent, 'id');            
            if (!$result) {
                $newId = 0;
            } else {
                $newId = (int)$db->insertid();                 
            }          

            //insert event in categories
            foreach ($parentCategories as $parentCategorie) {
                $newAssoc = new stdClass();
                $newAssoc->event_id = $newId;
                $newAssoc->category_id = $parentCategorie;                        
                $result = $db->insertObject('#__eb_event_categories', $newAssoc, 'id');            
                unset($newAssoc);
            }           

            return $newId;           
       }
       
        /**
        * Convertit une date afin qu'elle soit correctement formatée pour être insérée
        * dans la base de données
        * 
        * @param type $myDate
        */
        public static function convertDateToMySQL($myDate = '') {

              $dateFormatee = '';

              if($myDate !== '') {
                  $dateFormatee = str_replace ("/", "-", $myDate);
                  $dateFormatee = JFactory::getDate($dateFormatee)->toSql();
              } else {
                  $dateFormatee = JFactory::getDate()->toSql();                  
              }

              return  $dateFormatee;

         }
            
        /**
         * Renvoie un tableau contenant la liste des produits, leur quantités et leurs prix
         * à partir du code de la famille de produits
         * 
         * @param type $codeFamilleProduit : Si non renseigné, renvoie tous les produits
         * @param type $uniquementPublie  : Si égal à true, ne recherche que dans les produits publiés sinon toutes
         * @return int
         */
        public static function getProductsDetails($codeFamilleProduit = '', $uniquementPublie = true) {
            
            $db = JFactory::getDBO();	
            
            //cherche tous les produits de la famille de produits            		
            $query = $db->getQuery(true);
            $query->select($db->quoteName(array('#__categories.title', "#__categories.metakey", '#__content.id', '#__content.title', '#__fieldsattach.title', '#__fieldsattach_values.value'), array('nomfamille', 'codefamille', 'idproduit','nomproduit','nomchamp', 'valeurchamp')));			
            $query->from($db->quoteName('#__categories'));
            $query->join('INNER', $db->quoteName('#__content') . ' ON (' . $db->quoteName('#__content.catid') . ' = ' . $db->quoteName('#__categories.id') . ')');
            $query->join('INNER', $db->quoteName('#__fieldsattach_values') . ' ON (' . $db->quoteName('#__fieldsattach_values.articleid') . ' = ' . $db->quoteName('#__content.id') . ')');
            $query->join('INNER', $db->quoteName('#__fieldsattach') . ' ON (' . $db->quoteName('#__fieldsattach.id') . ' = ' . $db->quoteName('#__fieldsattach_values.fieldsid') . ')');
            $query->where($db->quoteName("#__categories.metakey")." LIKE '%".ECaracObjet::ECaracObjetRole."=".ERoleObjet::ERoleObjetFamilleProduits."%'");
            
            if ($codeFamilleProduit !== '') {
                $query->where($db->quoteName("#__categories.metakey")." LIKE '%".ECaracObjet::ECaracObjetCodeFamilleProduit."=".$codeFamilleProduit."%'");
            }
            
            if ($uniquementPublie === true) {
                $query->where($db->quoteName("#__content.state")." = 1 ");
            };
            
            $query->order($db->quoteName('#__categories.title') . ' ASC');
            $query->order($db->quoteName('#__content.title') . ' ASC');
            $query->order($db->quoteName('#__fieldsattach.title') . ' ASC');
            
            $db->setQuery($query);
            $resultatsBruts = $db->loadAssocList();
            
            $results = self::getCustomParameters($resultatsBruts, 'codefamille', ECaracObjet::ECaracObjetCodeFamilleProduit);
            
            /*
             * reforme le tableau sous forme arborescente : 1 ligne par produit, chaque produit étant un tableau
             * contenant les attributs du produit et leur valeur
             * 
             */            
            $compteur = 0;            
            $produits = array();            
            while ($compteur < count($results)) {                
                $detailProduits = array();
                $idProduitLu = $results[$compteur]['idproduit'];
                $detailProduits['idproduit'] = $idProduitLu;
                $detailProduits['nomproduit'] = $results[$compteur]['nomproduit']; 
                $detailProduits['codefamille'] = $results[$compteur]['codefamille']; 
                
                while ($idProduitLu === $results[$compteur]['idproduit']) {
                    $detailProduits[$results[$compteur]['nomchamp']] = $results[$compteur]['valeurchamp'];
                    $compteur += 1;
                }                
                array_push($produits, $detailProduits);                
            }
            
            return $produits;
       
         }
         
          /** Lit les valeurs de champ custo d'une opération
         * 
         * @param type $codeOperation
         * @return type
         */
        function chercherChampsCusto ($codeOperation) {
            $db = JFactory::getDBO();	
            $query = $db->getQuery(true);

            $query->select($db->quoteName(array('#__eb_events.custom_fields'), array('params')));			
            $query->from($db->quoteName("#__eb_events"));
            $query->join('INNER', $db->quoteName('#__eb_event_categories') . ' ON (' . $db->quoteName('#__eb_events.id') . ' = ' . $db->quoteName('#__eb_event_categories.event_id') . ')');
            $query->join('INNER', $db->quoteName('#__eb_categories') . ' ON (' . $db->quoteName('#__eb_event_categories.category_id') . ' = ' . $db->quoteName('#__eb_categories.id') . ')');
            $query->where($db->quoteName("#__eb_categories.meta_keywords")." LIKE '%".ECaracObjet::ECaracObjetCodeOperation."=".$codeOperation."%'");
            $query->where($db->quoteName("#__eb_events.meta_keywords")." LIKE '%".ECaracObjet::ECaracObjetRole."=".ERoleObjet::ERoleObjetSuiviOperation."%'");
   
            $db->setQuery($query);
            $resultats = $db->loadAssocList();
            if (count($resultats) == 1) {
                $params = explode(NEW_LINE, $resultats[0]['params']);
            };
            return $params;            
        }
         
         /**
          * créée des items utilisables pour le module 'invoice' à partir des produits de l'AMAP
          * matérialisés par des articles Joomla. Ecrase les anciens et recréé tous les items à chaque fois.
          */
         public static function creerProduitsPourContrats () {
             
             //vide l'ancienne définition des items             
            $db = JFactory::getDbo();
            $query = $db->getQuery(true);
            $query->delete($db->quoteName('#__invoices_templateitems'));
            $db->setQuery($query);
            $resultat = $db->query();
             
             //lit les caractéristiques produits et les place dans la table
             $produits = self::getProductsDetails();
             
             foreach ($produits as $produit) {
                $sku = $produit[ECaracProduit::ECaracProduitReference];
                $prixUnitaire = $produit[ECaracProduit::ECaracProduitPrixUnitaire];
                $quantiteLot = $produit[ECaracProduit::ECaracProduitQuantiteLot];                
                $nom = $produit['nomproduit'];
                $description = "produit de la famille '".$produit['codefamille']."'";
                 
                $newItem = new stdClass();
                $newItem->name = $nom;    
                $newItem->value = $prixUnitaire;
                $newItem->amount = $quantiteLot;
                $newItem->sku = $sku; 
                $newItem->desc = $description;

                // Insert the object into the invoice table
                $result = $db->insertObject('#__invoices_templateitems', $newItem, 'id');            
                unset($newItem);                 
             }            
         }
    }
?>